package gwt.immunology.client.components;

import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class DialogBoxEx extends DialogBox {
    private Button close = null;
    private Widget closeWidget = null;
    
    public DialogBoxEx() {
        this("&nbsp;");
    }
    
    public DialogBoxEx(String captionTitle) {
        setStyleName("immunologyDialogBox");
        setGlassStyleName("glassDialogBox");
        setModal(true);
        setGlassEnabled(true);
        closeWidget = getClosePanel().asWidget();
        setHTML(captionTitle);
    }

    private HorizontalPanel getClosePanel() {
        HorizontalPanel buttonPanel = new HorizontalPanel();
        buttonPanel.addStyleName("closeButtonPanel");
        Label closeLabel = new Label("Close");
        close = new Button();
        closeLabel.addStyleName("closeLabel");
        close.addStyleName("closeButton");
        buttonPanel.add(closeLabel);
        buttonPanel.add(close);
        buttonPanel.setCellVerticalAlignment(close, HasVerticalAlignment.ALIGN_MIDDLE);
        buttonPanel.setCellVerticalAlignment(closeLabel, HasVerticalAlignment.ALIGN_MIDDLE);
        return buttonPanel;
    }

    @Override
    public void setHTML(String html) {
        if (closeWidget != null) {
            setCaption(html, closeWidget);
        } else {
            super.setHTML(html);
        }
    }

    @Override
    public void setHTML(SafeHtml html) {
        setHeight(html.asString());
    }

    private void setCaption(String txt, Widget w) {
        HTML title = new HTML(txt);
        title.addStyleName("dialogBoxTitle");
        HorizontalPanel captionPanelHolder = new HorizontalPanel();
        captionPanelHolder.setStyleName("caption");
        
        HorizontalPanel captionPanel = new HorizontalPanel();
        captionPanel.setCellHorizontalAlignment(title, HasHorizontalAlignment.ALIGN_LEFT);
        captionPanel.add(title);
        captionPanel.setCellVerticalAlignment(title, HasVerticalAlignment.ALIGN_MIDDLE);
        
        captionPanel.setCellHorizontalAlignment(w, HasHorizontalAlignment.ALIGN_RIGHT);
        captionPanel.add(w);

        captionPanel.setCellWidth(w, "5%");
        captionPanel.setStyleName("innerCaptionPanel");
        captionPanelHolder.add(captionPanel);

        Element td = getCellElement(0, 1);
        
        td.setInnerHTML("");

        td.appendChild(captionPanelHolder.getElement());
    }

    private class DialogBoxCloseHandler {
        public void onClick(Event event) {
            hide();
        }
    }

    protected boolean isHeaderCloseControlEvent(NativeEvent event) {
        return isWidgetEvent(event, closeWidget);
    }

    @Override
    public void onBrowserEvent(Event event) {
        if (isHeaderCloseControlEvent(event)) {

            switch (event.getTypeInt()) {
            case Event.ONMOUSEUP:
            case Event.ONCLICK:
                new DialogBoxCloseHandler().onClick(event);
                break;
            case Event.ONMOUSEOVER:
                break;
            case Event.ONMOUSEOUT:
                break;
            }

            return;
        }

        super.onBrowserEvent(event);
    }

    public boolean onEventPreview(Event event) {
        if ((DOM.eventGetType(event) & Event.MOUSEEVENTS) != 0) {
            /*
             * Firefox: the client area stops at the scroll bar. If a mouse
             * event is outside the client area, it is targeted to the
             * scrollbar. Override default behavior to allow these events.
             */
            int clientX = DOM.eventGetClientX(event);
            int clientY = DOM.eventGetClientY(event);
            if (clientX > Window.getClientWidth() || clientY > Window.getClientHeight()) {
                return true;
            }
        }
        return super.onEventPreview(event);
    }

    protected boolean isWidgetEvent(NativeEvent event, Widget w) {
        EventTarget target = event.getEventTarget();

        if (Element.is(target)) {
            boolean t = w.getElement().isOrHasChild(Element.as(target));
            return t;
        }
        return false;
    }

    public void center() {
        super.center();
        int realTop = (getPopupTop() - Window.getScrollTop());
        setPopupPosition(getPopupLeft(), realTop > 40 ? realTop + Window.getScrollTop() : 40 + Window.getScrollTop());
    }

    @Override
    public void show() {
        super.show();
        center();
    }
}
